#ifndef CLASS_MANAGER
#define CLASS_MANAGER
#include "BJ.h"

/* Container class to create and store various object groups */
template<class T>
class ObjectManager
{
    public :

        ObjectManager
        (
            void
        ): _nextAvailableIndex(0)
        {
            //cout << "Construct an object manager at " << this << endl;
        }

        virtual ~ObjectManager
        (
            void
        )
        {
            for
            (
                _objectListIter = _objectList.begin();
                _objectListIter != _objectList.end();
                ++_objectListIter
            )
            {
                delete *_objectListIter;
            }

            //cout << "Destroy an object manager at " << this << endl;
        }

        T* create
        (
            void
        )
        {
            T* object = new T(_nextAvailableIndex++);
            _objectList.push_back(object);

            return object;
        }

        void for_each
        (
            bool (*iPFunctionAction)(T *)
        )
        {
            _objectListIter = _objectList.begin();
            while (_objectListIter != _objectList.end())
            {
                if ((*iPFunctionAction)((T *) *_objectListIter))
                {
                    typename list<T*>::iterator tempIt = _objectListIter;
                    ++_objectListIter;
                    delete *tempIt;
                    _objectList.erase(tempIt);
                }
                else
                {
                    ++_objectListIter;
                }
            }
        }
        void for_matching
        (
            bool (*iPFunctionAction)(T *),
            bool (*iPFunctionCondition)(T *)
        )
        {
            objectListIter = _objectList.begin();
            while (objectListIter != _objectList.end())
            {
                if ((*iPFunctionCondition)((T *) *objectListIter))
                {
                    typename list<T*>::iterator tempIt = objectListIter;
                    ++objectListIter;
                    delete *tempIt;
                    objectList.erase(tempIt);
                }
                else
                {
                    ++objectListIter;
                }
            }
        }
        
        T * search
        (
            bool (*iPFunctionCondition)(T *)
        )
        {
            for (objectListIter = objectList.begin();
            objectListIter != objectList.end();
            ++objectListIter)
            {
                if ((*iPFunctionCondition)((T *) *objectListIter))
                {
                    return *objectListIter;
                }
            }
            return NULL;
        }

        int _nextAvailableIndex;
        typename list<T*>::iterator _objectListIter;
        list<T*> _objectList;
};

/* A function suitable for the for_each function */
template <class T>
bool refresh
(
T *iPClass
)
{
    return iPClass->refresh();
}

#endif